/**
 * 获取表单html，修正jquery html方法获取不到修改后的值
 */
(function ($) {
    var oldHTML = $.fn.html;
    $.fn.formhtml = function () {
        if (arguments.length) return oldHTML.apply(this, arguments);
        $("input,textarea,button", this).each(function () {
            this.setAttribute('value', this.value);
        });
        $(":radio,:checkbox", this).each(function () {
            if (this.checked) this.setAttribute('checked', 'checked');
            else this.removeAttribute('checked');
        });
        $("option", this).each(function () {
            if (this.selected) this.setAttribute('selected', 'selected');
            else this.removeAttribute('selected');
        });
        return oldHTML.apply(this);
    };
})(jQuery);
//js验证
var valid = {
    //是否为空
    isEmpty: function (str) {
        return str === "" || str === null || str === undefined;
    },
    //是否为邮件
    isEmail: function (str) {
        var reg = /^\w+((-w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
        if (reg.test(str)) return true;
    },
    //是否为手机号
    isMobile: function (str) {
        var a = /^1\d{10}$/, s = $.trim(str);
        if (a.test(s)) return true;
    },
    //是否汉字
    isCN: function (str) {
        var s = $.trim(str), reg = /^[\u4e00-\u9fa5]+$/;
        return reg.test(s);
    },
    //是否密码
    isPwd: function (str) {
        var reg = /^[A-Za-z0-9_-]+$/;
        if (reg.test(str)) return true;
    },
    //是否为微信号
    isWx: function (str) {
        var rex = /^[a-zA-Z\d_]{5,}$/;
        return rex.test($.trim(str));
    },
    //是否全为数字
    isNum: function (num) {
        var rex = /^[0-9]+$/;
        return rex.test($.trim(num));
    },
    //是否浮点数
    isFloat:function(num){
        var rex = /^[+]{0,1}(\d+)$|^[+]{0,1}(\d+\.\d+)$/;
        return rex.test($.trim(num));
    },
    //是否为热线电话
    isPhone: function (num) {
        var rex = /^[0-9]([0-9]|-)*[0-9]$/;
        return rex.test($.trim(num));
    },
    //是否为钱数
    /*isFloat: function (n) {
        return !isNaN(n);
    },*/
    //判断是否为url地址
    isUrl: function (str) {
        var rex = /^(http|https):\/\/[^\s]+$/;
        return rex.test($.trim(str));
    }
};
//通用辅助方法
var helper = {
    calc: function (arg1, arg2, operator) {
        var oper = ['+', '-', '*', '/'];
        // 不合法的运算
        if (isNaN(arg1) || isNaN(arg2) || oper.indexOf(operator) < 0) return NaN;
        // 除以0
        if (operator === '/' && Number(arg2) === 0) return Infinity;
        // 和0相乘
        if (operator === '*' && Number(arg2) === 0) return 0;
        // 相等两个数字相减
        if ((arg1 === arg2 || Number(arg1) === Number(arg2)) && operator === '-') return 0;
        var r1, r2, max, _r1, _r2;
        try {
            r1 = arg1.toString().split(".")[1].length
        } catch (e) {
            r1 = 0
        }
        try {
            r2 = arg2.toString().split(".")[1].length
        } catch (e) {
            r2 = 0
        }
        max = Math.max(r1, r2)
        _r1 = max - r1;
        _r2 = max - r2;
        if (_r1 !== 0) {
            arg1 = arg1 + '0'.repeat(_r1)
        }
        if (_r2 !== 0) {
            arg2 = arg2 + '0'.repeat(_r2)
        }
        arg1 = Number(arg1.toString().replace('.', ''));
        arg2 = Number(arg2.toString().replace('.', ''));
        var r3 = operator === '*' ? (max * 2) : (operator === '/' ? 0 : max);
        var newNum = eval(arg1 + operator + arg2);
        if (r3 !== 0) {
            var nStr = newNum.toString();
            nStr = nStr.replace(/^-/, '');
            if (nStr.length < r3 + 1) {
                nStr = '0'.repeat(r3 + 1 - nStr.length) + nStr;
            }
            nStr = nStr.replace(new RegExp('(\\\d{' + r3 + '})$'), '.$1');
            if (newNum < 0) {
                nStr = '-' + nStr;
            }
            newNum = nStr * 1;
        }
        return newNum;
    },
    createTab(opt) {
        var defaultOpt = {refresh: false};
        var option = $.extend({}, defaultOpt, opt);
        if (self != top) {
            top.$(parent.document).data('multitabs').create(option, true);
        } else {
            location.href = option.url;
        }
    },
    closeTabOthers() {
        parent.$(parent.document).data('multitabs').closeOthers();
    },
    closeTabAll() {
        parent.$(parent.document).data('multitabs').closeAll();
    },
    closeTabById(id) {
        parent.$(parent.document).data('multitabs').closeById(id);
    },
    closeTabByUrl(url) {
        parent.$(parent.document).data('multitabs').closeByUrl(url);
    },
    closeCurrent() {
        if (self != top) {
            parent.$(parent.document).data('multitabs').closeCurrent();
        } else {
            window.close();
        }
    },
    /**参数说明：
     * 根据长度截取先使用字符串，超长部分追加…
     * str 对象字符串
     * len 目标字节长度
     * 返回值： 处理结果字符串
     */
    cutString: function (str, len) {
        //length属性读出来的汉字长度为1
        if (str.length * 2 <= len) {
            return str;
        }
        var strlen = 0;
        var s = "";
        for (var i = 0; i < str.length; i++) {
            s = s + str.charAt(i);
            if (str.charCodeAt(i) > 128) {
                strlen = strlen + 2;
                if (strlen >= len) {
                    return s.substring(0, s.length - 1) + "...";
                }
            } else {
                strlen = strlen + 1;
                if (strlen >= len) {
                    return s.substring(0, s.length - 2) + "...";
                }
            }
        }
        return s;
    },
    /**
     * json转字符串
     * @param json
     * @returns {string}
     */
    json2str: function (json) {
        return JSON.stringify(json);
    },
    /**
     * 刷新页面
     * @returns {boolean}
     */
    refresh: function () {
        window.location.reload(true);
    },
    /**
     * 返回
     */
    back: function () {
        window.history.go(-1);
    },
    /**
     * 跳转
     * @param url
     */
    location: function (url) {
        window.location.href = url;
    },
    /**
     * 全选
     * @param dom
     */
    checkAll: function (dom) {
        $(dom + " :checkbox").prop("checked", true);
    },
    /**
     * 反选
     * @param dom
     */
    checkOther: function (dom) {
        $(dom + " :checkbox").each(function () {
            $(this).prop("checked", !$(this).prop("checked"));
        });
    },
    /**
     * 获取复选款值
     * @param dom
     * @returns {[]}
     */
    getCheckboxValue: function (dom) {
        const reVal = [];
        $(dom).find("input[type='checkbox']").each(function () {
            if ($(this).prop("checked")) {
                reVal.push($(this).val());
            }
        });
        return reVal;
    },
    /**
     * 操作后提示
     * @param msg
     * @param icon
     * @param callFn
     * @returns {boolean}
     */
    tips: function (msg, icon, callFn) {
        const opt = valid.isNum(icon) ? {icon: icon, time: 1200} : {time: 1200};
        layer.msg(msg, opt, function () {
            if (typeof (callFn) != "undefined") {
                callFn();
            }
        });
    },
    /**
     * 封装ajax请求
     * @param opt
     */
    getAjax: function (opt) {
        const defaultConfig = {
            type: 'post',
            cache: true,
            async: true,
            dataType: 'json',
            beforeSend: function () {
                helper.loading('show');
            },
            error: function () {
                layer.alert('与服务器断开连接！');
                return false;
            },
            complete: function () {
                helper.loading('hide');
            }
        };
        const config = $.extend({}, defaultConfig, opt);
        $.ajax(config);
    },
    /**
     * loading
     * @param $mode
     * @returns {boolean}
     */
    loading: function ($mode) {
        var $loadingEl = $('#loading');
        $mode = $mode || 'show';
        if ($mode === 'show') {
            if ($loadingEl.length) {
                $loadingEl.fadeIn(250);
            } else {
                $('body').prepend(
                    '<div id="loading"><div class="spinner-border text-primary" role="status"><span class="sr-only">Loading...</span></div></div>'
                );
            }
        }
        if ($mode === 'hide') {
            if ($loadingEl.length) {
                $loadingEl.fadeOut(250);
            }
        }
        return false;
    },
    /**
     * 图片懒加载
     * @param throttle
     */
    lazy: function (throttle) {
        var t = throttle || 0;
        Do('echo', function () {
            echo.init({
                offset: 0, //离可视区域多少像素的图片可以被加载
                throttle: t //图片延迟多少毫秒加载
            });
        });
    },
    /*
     字符串拼接,记得将反斜杠替换为正斜杠
     var str = helper.heredoc(function () {\*
     {@each list as row}
     <li>${row.title}</li>
     {@/each}
     *\})
     */
    heredoc: function (fn) {
        return fn.toString().split('\n').slice(1, -1).join('\n') + '\n'
    },
    /**
     * 获取url地址栏参数
     * @return {string}
     */
    GetQueryString: function (name) {
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
        var r = window.location.search.substr(1).match(reg);
        if (r != null) return unescape(r[2]);
        return '';
    },
    /**
     * 判断是否手机
     * @returns {boolean}
     */
    isMobile: function () {
        var ua = navigator.userAgent;
        var ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
            isIphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
            isAndroid = ua.match(/(Android)\s+([\d.]+)/),
            isMobile = isIphone || isAndroid;
        return !!isMobile;
    },
    /**
     * 获取检索参数name用@隔开，需单独传递参数使用字段@own
     * @param dom
     */
    getSearchParams: function (dom) {
        var obj = dom || '#search-form';
        var params = {};
        var filter = [];
        if ($(obj).length > 0) {
            var formData = $(obj).serializeArray();
            for (var i = 0; i < formData.length; i++) {
                var formInfo = formData[i];
                var arr = formInfo.name.split('@');
                var field = arr[0];
                if (arr.length == 1) { //单独传输
                    params[field] = formInfo.value;
                } else {
                    filter.push({field: field, op: arr[1], value: formInfo.value});
                }
            }
        }
        params.filter = filter;
        return params;
    },
    /**
     * bootstrap-table封装
     * @param opt
     * @param dom
     */
    bootstrapTable: function (opt, dom) {
        var obj = dom || '#grid';
        var defaultOption = {
            iconsPrefix: "mdi",
            icons: {
                paginationSwitchDown: "mdi-arrow-down",
                paginationSwitchUp: "mdi-arrow-up",
                refresh: "mdi-refresh",
                toggleOff: "mdi-set-left",
                toggleOn: "mdi-set-right",
                columns: "mdi-view-list",
                fullscreen: "mdi-fullscreen",
                detailOpen: "mdi-plus",
                detailClose: "mdi-minus",
                export: "mdi-download"
            },
            uniqueId: 'id',
            sortOrder:'desc',
            toolbar: '.toolbar',
            pagination: true,
            pageSize: 20,
            sidePagination: "server",
            showJumpTo: true,
            paginationSuccessivelySize: 3,
            method: "post",
            queryParamsType: "page",
            pageList: [20, 40, 80, 100, 500, 'all'],
            showFullscreen: false,
            showColumns: true,
            showRefresh: true,
            showToggle: false,
            showExport: true,
            smartDisplay: true,
            exportTypes: ['excel', 'csv', 'json', 'xml', 'txt'],
            exportOptions: {
                ignoreColumn: ['checkbox', 'operate'] //导出忽略单选/复选列/操作列
            },
            clickToSelect: true
        };
        var option = $.extend({}, defaultOption, opt);
        var bodyWidth = $(document.body).outerWidth();
        var bodyHeight = $(document.body).outerHeight();
        if (!option.hasOwnProperty('height')) {
            if (bodyWidth > 1023) {
                option.height = bodyHeight - 90;
            }
        }
        if (option.hasOwnProperty('diffHeight')) {
            option.height = bodyHeight - parseInt(option.diffHeight);
        }
        if (!option.hasOwnProperty('queryParams')) {
            option.queryParams = function (params) {
                var searchParams = helper.getSearchParams();
                return $.extend({}, params, searchParams);
            }
        }
        Do('bootstrap-table', 'export', function () {
            $(obj).bootstrapTable(option);
        });
    },
    treeTable: function (opt, dom) {
        var grid = dom || '#grid';
        var defaultOption = {
            expanderCollapsedClass: "mdi mdi-folder",
            expanderExpandedClass: "mdi mdi-folder-open",
            saveState: true
        };
        var options = $.extend({}, defaultOption, opt);
        Do('tree-grid', function () {
            $(grid).treegrid(options);
        });
    },
    /**
     * bootstrap-table刷新表格封装
     * @param dom
     */
    refreshTable: function (dom) {
        var obj = dom || '#grid';
        $(obj).bootstrapTable('refresh', {pageNumber: 1});
    },
    /**
     * ajax分页封装
     * @param options
     * @param dom
     */
    pagination: function (options, dom) {
        var obj = dom || '#page';
        var params = options.params || {};
        Do('pagination', function () {
            var defaultConfig = {
                locator: 'rows',
                totalNumberLocator: function (response) {
                    return response.total;
                },
                className: 'paginationjs-theme-primary',
                pageSize: 20,
                showGoInput: false,
                showGoButton: false,
                autoHidePrevious: true,
                autoHideNext: true,
                ajax: {
                    type: 'post',
                    data: params,
                    beforeSend: function () {
                        helper.loading('show');
                    },
                    complete: function () {
                        helper.loading('hide');
                    }
                }
            };
            console.log(options);
            var config = $.extend({}, defaultConfig, options);
            $(obj).pagination(config);
        });
    },
    renderSize: function (fileSize) {
        if (null == fileSize || fileSize == '') return "0 Bytes";
        var unitArr = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
        var index;
        var srcsize = parseFloat(fileSize);
        index = Math.floor(Math.log(srcsize) / Math.log(1024));
        var size = srcsize / Math.pow(1024, index);
        size = size.toFixed(2);//保留的小数位数
        return size + unitArr[index];
    },
    /**
     * 友好时间显示
     * @param timestamp
     * @returns {string|*}
     */
    dateDiff: function (timestamp) {
        // 补全为13位
        var arrTimestamp = (timestamp + '').split('');
        for (var start = 0; start < 13; start++) {
            if (!arrTimestamp[start]) {
                arrTimestamp[start] = '0';
            }
        }
        timestamp = arrTimestamp.join('') * 1;
        var minute = 1000 * 60;
        var hour = minute * 60;
        var day = hour * 24;
        var halfamonth = day * 15;
        var month = day * 30;
        var now = new Date().getTime();
        var diffValue = now - timestamp;

        // 如果本地时间反而小于变量时间
        if (diffValue < 0) return '不久前';
        // 计算差异时间的量级
        var monthC = diffValue / month;
        var weekC = diffValue / (7 * day);
        var dayC = diffValue / day;
        var hourC = diffValue / hour;
        var minC = diffValue / minute;
        // 数值补0方法
        var zero = function (value) {
            if (value < 10) return '0' + value;
            return value;
        };
        // 使用
        if (monthC > 12) {
            // 超过1年，直接显示年月日
            return (function () {
                var date = new Date(timestamp);
                return date.getFullYear() + '年' + zero(date.getMonth() + 1) + '月' + zero(date.getDate()) + '日';
            })();
        } else if (monthC >= 1) {
            return monthC + "月前";
        } else if (weekC >= 1) {
            return weekC + "周前";
        } else if (dayC >= 1) {
            return dayC + "天前";
        } else if (hourC >= 1) {
            return hourC + "小时前";
        } else if (minC >= 1) {
            return minC + "分钟前";
        }
        return '刚刚';
    },
    /**
     * 格式化时间戳
     * @param timestamp
     * @param formats 1. Y-m-d 2. Y-m-d H:i:s 3. Y年m月d日 4. Y年m月d日 H时i分
     * @returns {string}
     */
    dateFormat: function (timestamp, formats) {
        if (valid.isEmpty(timestamp) || !valid.isNum(timestamp)) return '-';
        if (timestamp.length !== 10 && timestamp.length !== 13) return '-';
        if (timestamp.length === 10) timestamp = timestamp * 1000;
        formats = formats || 'Y-m-d';
        //不够两位数补零
        var zero = function (value) {
            if (value < 10) return '0' + value;
            return value;
        };
        var myDate = timestamp ? new Date(timestamp) : new Date();
        var year = myDate.getFullYear();
        var month = zero(myDate.getMonth() + 1);
        var day = zero(myDate.getDate());

        var hour = zero(myDate.getHours());
        var minite = zero(myDate.getMinutes());
        var second = zero(myDate.getSeconds());

        return formats.replace(/Y|m|d|H|i|s/ig, function (matches) {
            return ({
                Y: year,
                m: month,
                d: day,
                H: hour,
                i: minite,
                s: second
            })[matches];
        });
    },
    /**
     * 确认后操作
     * @param obj
     * @param callFn
     */
    doConfirm: function (obj, callFn) {
        var data = $(obj).data();
        var msg = valid.isEmpty(data.msg) ? '确认操作吗？' : data.msg;
        layer.confirm(msg, {icon: 3}, function (index) {
            helper.getAjax({
                url: data.url,
                data: data.params,
                success: function (res) {
                    if (res.code == 1) {
                        if (typeof (callFn) == "undefined") {
                            helper.refreshTable();
                        } else if (callFn == 'refresh') {
                            helper.refresh();
                        } else if (callFn.substring(0, 4) == 'url:') {
                            var arr = callFn.split(':');
                            helper.location(arr[1]);
                        } else {
                            callFn(res);
                        }
                    } else {
                        helper.tips(res.msg);
                    }
                }
            });
            layer.close(index);
        });
    },
    /**
     * 弹框操作
     * @param obj
     */
    doDialog: function (obj) {
        var url = $(obj).data('url'),
            width = $(obj).data('width') || '80%',
            height = $(obj).data('height') || '90%',
            offset = $(obj).data('offset') || '30px',
            title = $(obj).data('title') || '操作窗口';
        var index = layer.open({
            type: 2,
            title: title,
            offset: offset,
            area: [width, height],
            closeBtn: 1,
            shade: 0.2,
            isOutAnim: false,
            shadeClose: true,
            resize: false,
            fixed: false, //不固定
            content: url
        });
        var bodyWidth = $(document.body).width();
        if (bodyWidth < 768) layer.full(index);
    },
    /**
     * layer适配小屏幕
     * @param obj
     */
    open: function (obj) {
        var index = layer.open(obj);
        var bodyWidth = $(document.body).width();
        if (bodyWidth < 768) layer.full(index);
    },
    /**
     * 删除行
     * @param obj
     * @param callFn
     */
    delRow: function (obj, callFn) {
        $(obj).closest('.item-row').remove();
        if (typeof callFn != 'undefined') {
            callFn(obj);
        }
    },
    /**
     * 上移
     * @param obj
     */
    upMove: function (obj) {
        var leftMove = $(obj).closest('.item-row');   //当前行
        var prevMove = leftMove.prev('.item-row');               //上一个同级元素
        if (prevMove.length > 0) {                        //存在上一个同级元素
            prevMove.insertAfter(leftMove);           //就把它移动到前面
        }
    },
    /**
     * 下移
     * @param obj
     */
    downMove: function (obj) {
        var rightMove = $(obj).closest('.item-row');
        var nextMove = rightMove.next('.item-row');
        if (nextMove.length > 0) {
            nextMove.insertBefore(rightMove);
        }
    },
    //将base64转换为文件  
    dataURLtoFile: function (base64, filename) {
        var arr = base64.split(','), mime = arr[0].match(/:(.*?);/)[1],
            str = atob(arr[1]), n = str.length, u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = str.charCodeAt(n);
        }
        return new File([u8arr], filename, {type: mime});
    },
    //格式化金额显示
    formatMoney:function (value) {
        if (value) {
            if (isNaN(value)) {
                return value;
            }
            value = typeof value == 'string' ? parseFloat(value) : value // 判断是否是字符串如果是字符串转成数字
            value = value.toFixed(2); // 保留两位
            console.log(value)
            value = parseFloat(value); // 转成数字
            value = value.toLocaleString(); // 转成金额显示模式
            // 判断是否有小数
            if (value.indexOf('.') === -1) {
                value = '￥' + value + '.00';
            } else {
                console.log(num.split('.')[1].length)
                // num = num.split('.')[1].length < 2 ? '￥' + num + '0' : '￥' + num;
            }
            return value;
        } else {
            return '';
        }
    }

};
//表单辅助方法
var formHelper = {
    init: function () {
        this.laydate();
        this.number();
        this.tags();
        this.ckEditor();
        this.ace();
        this.area();
        this.selectpage();
        this.inputGroup();
        this.upload();
        this.uploadVideo();
        this.color();
    },
    /**
     * 表单提交
     * @param opt
     * @param dom
     */
    subForm: function (opt, dom) {
        var obj = dom || '#form';
        var defaultConfig = {
            btnSubmit: ".btn-sub",
            btnReset: ".btn-reset",
            ajaxPost: true,
            tipSweep: true,
            label: '.control-label',
            tiptype: function (msg, o, cssctl) {
                if (o.type == 3) {
                    o.obj.closest('.form-group').addClass('has-error');
                    $(obj).find('.error-msg').show().html('<i class="mdi mdi-information"></i> ' + msg);
                } else {
                    o.obj.closest('.form-group').removeClass('has-error');
                    $(obj).find('.error-msg').html('').hide();
                }
            },
            beforeCheck: function (curform) {
                if (typeof CKEDITOR != 'undefined') { //同步编辑器
                    for (ck in CKEDITOR.instances) {
                        CKEDITOR.instances[ck].updateElement();
                    }
                }
            },
            beforeSubmit: function (curform) {
                helper.loading('show');
                $(obj).find('.btn-sub').attr("disabled", "disabled"); //禁用按钮
                $(obj).find('.btn-reset').attr("disabled", "disabled"); //禁用按钮
            },
            callback: function (res) {
                helper.loading('hide');
                $(obj).find('.btn-sub').removeAttr("disabled"); //启用按钮
                $(obj).find('.btn-reset').removeAttr("disabled"); //启用按钮
                let url = $(obj).data('url');
                if (res.code == 1) {
                    var call = $(obj).data('call') || '';
                    let action = $(obj).data('action') || '';
                    if (typeof opt == 'function' && action == '') {
                        opt(res);
                        let index = parent.layer.getFrameIndex(window.name);
                        parent.layer.close(index);
                    } else {
                        let benText = action == 'close' ? '关闭页面' : '返回列表';
                        if (call == '') {
                            layer.confirm('操作成功', {
                                closeBtn: 0,
                                icon: 1,
                                btn: ['继续操作', benText] //按钮
                            }, function () {
                                helper.refresh();
                            }, function () {
                                if (action == 'close') {
                                    if (!valid.isEmpty(url)){ //刷新指定页面
                                        let iframe = parent.$(parent.document).find("iframe[src='" + url + "']");
                                        if (iframe.length > 0) {
                                            let id = '#' + iframe.attr('id');
                                            top.$(id).contents().find('#search-btn').click();
                                            //helper.createTab({url: url});
                                            //iframe.attr('src',url);
                                        }
                                    }
                                    helper.closeCurrent();
                                } else { //默认返回列表
                                    if (!valid.isEmpty(url)) location.href = url;
                                }
                            });
                        } else {
                            if (call == "refreshSelfPage") helper.refresh();
                            if (call == "refreshPage") parent.helper.refresh();
                            if (call == 'refreshTable') parent.helper.refreshTable();
                            if (call == 'url'){
                                var locationUrl = valid.isEmpty(url) ? res.url : url;
                                helper.location(locationUrl);
                            }
                            if (action==''){
                                let index = parent.layer.getFrameIndex(window.name);
                                parent.layer.close(index);
                            }
                        }
                    }
                } else {
                    $(obj).find('.error-msg').show().html('<i class="mdi mdi-information"></i> ' + res.msg);
                }
            }
        };
        var config = defaultConfig;
        if (typeof opt == 'object') {
            config = $.extend({}, defaultConfig, opt);
        }
        Do('valid', function () {
            $(obj).Validform(config);
        });
    },
    copy: function () {
        Do('copy', function () {
            var clipboard = new ClipboardJS('.f-copy');
            clipboard.on('success', function (e) {
                layer.msg('拷贝成功');
            });
        });
    },
    number: function () {
        $('.f-number').each(function () {
            var type = $(this).data('type');
            $(this).keyup(function () {
                if (type == 'number') {
                    $(this).val($(this).val().replace(/[^-\d]/g, ''));
                }
                if (type == 'float') {
                    $(this).val($(this).val().replace(/[^-\d.]/g, ''));
                }
            }).bind("paste", function () {  //CTR+V事件处理
                if (type == 'number') {
                    $(this).val($(this).val().replace(/[^-\d]/g, ''));
                }
                if (type == 'float') {
                    $(this).val($(this).val().replace(/[^-\d.]/g, ''));
                }
            }).css("ime-mode", "disabled"); //CSS设置输入法不可用
        });
    },
    laydate: function () {
        if ($('.f-laydate').length > 0) {
            Do('laydate', function () {
                $('.f-laydate').each(function () {
                    var opt = $(this).data();
                    var defaultOption = {
                        elem: this,
                        done: function (value, date, endDate) {
                            var hours = endDate.hours;
                            var minutes = endDate.minutes;
                            var seconds = endDate.seconds;
                            if (hours == "0" && minutes == "0" && seconds == "0") {
                                $(".layui-laydate-footer [lay-type='datetime'].laydate-btns-time").click();
                                $(".laydate-main-list-1 .layui-laydate-content li ol li:last-child").click();
                                $(".layui-laydate-footer [lay-type='date'].laydate-btns-time").click();
                            }
                        }
                    };
                    var option = $.extend({}, defaultOption, opt);
                    laydate.render(option);
                });
            });
        }
    },
    color: function () {
        /*
        ishex: true, //是否使用16进制颜色值
        fillcolor: false,  //是否将颜色值填充至对象的val中
        target: null, //目标对象
        event: 'click', //颜色框显示的事件
        success: function () {
        }, //回调函数
        reset: function () {
        }
         */
        if ($('.f-color').length > 0) {
            Do('color', function () {
                $('.f-color').each(function () {
                    var opt = $(this).data();
                    if (opt.hasOwnProperty('success')) opt.success = function (o, color) {
                        return eval('f_success(o,color)')
                    }
                    if (opt.hasOwnProperty('reset')) opt.reset = function (obj) {
                        return eval('f_reset(obj)')
                    }
                    var defaultOption = {
                        fillcolor: true
                    };
                    var option = $.extend({}, defaultOption, opt);
                    $(this).colorpicker(option);
                });
            });
        }
    },
    selectpage: function () {
        if ($('.f-selectPage').length > 0) {
            Do('selectpage', function () {
                $('.f-selectPage').each(function () {
                    var opt = $(this).data();
                    var params = {searchField: opt.showField};
                    if (opt.hasOwnProperty('searchField')){
                        params.searchField = opt.searchField
                        delete opt.searchField;
                    }
                    opt.params = function () {
                        return params;
                    }
                    var defaultOption = {
                        keyField: 'id',
                        showField: 'name',
                        eAjaxSuccess: function (d) {
                            return d ? d : undefined;
                        }
                    };
                    if (opt.hasOwnProperty('formatItemFn')) {
                        defaultOption.formatItem = function (data) {
                            return eval(opt['formatItemFn'] + '(data)');
                        }
                    }
                    if (opt.hasOwnProperty('eSelectFn')) {
                        defaultOption.eSelect = function (data) {
                            return eval(opt['eSelectFn'] + '(data)');
                        }
                    }
                    if (opt.hasOwnProperty('eAjaxSuccessFn')) {
                        defaultOption.eAjaxSuccess = function (data) {
                            return eval(opt['eAjaxSuccessFn'] + '(data)');
                        }
                    }
                    if (opt.hasOwnProperty('eOpenFn')) {
                        defaultOption.eOpen = function (self) {
                            return eval(opt['eOpenFn'] + '(self)');
                        }
                    }
                    if (opt.hasOwnProperty('eTagRemoveFn')) {
                        defaultOption.eTagRemove = function (datas) {
                            return eval(opt['eTagRemoveFn'] + '(datas)');
                        }
                    }
                    if (opt.hasOwnProperty('eClearFn')) {
                        defaultOption.eClear = function () {
                            return eval(opt['eClearFn'] + '()');
                        }
                    }
                    var option = $.extend({}, defaultOption, opt);
                    $(this).selectPage(option);
                });
            });
        }
    },
    ace: function () {
        if ($('.f-ace').length > 0) {
            Do('ace', function () {
                $('.f-ace').each(function (i) {
                    var id = $(this).attr('id');
                    var data = $(this).data();
                    var theme = data.theme || 'chrome';
                    var mode = data.mode || 'html';
                    var readonly = data.readonly || false;
                    var html = $(this).html();
                    var editor = ace.edit(id);
                    editor.setOptions({
                        autoScrollEditorIntoView: true,
                    });
                    editor.setTheme("ace/theme/" + theme); //设置风格
                    editor.getSession().setMode("ace/mode/" + mode); //设置语言模式
                    document.getElementById(id).style.fontSize = '16px'; //设置字体大小
                    editor.setReadOnly(readonly); //设置编辑器只读
                    editor.setValue(html);
                    editor.getSession().on("change", function (e) {
                        $("textarea[name='" + id + "']").val(editor.getValue());
                    });
                    Do.setData('ace-' + id, editor);
                });
            })
        }
    },
    tags: function () {
        Do('tags', function () {
            $('.f-tags').tagsinput({
                trimValue: true, //去除标签空白
                focusClass: 'my-focus-class'
            });
        });
    },
    area: function () {
        if ($('.f-area').length > 0) {
            Do('city', function () {
                $('.f-area').each(function () {
                    var name = $(this).data('name') || 'area_code';
                    var inputObj = $(this).find("[name='" + name + "']");
                    var code = inputObj.val();
                    var option = $(this).data();
                    var defaultOption = {
                        code: code,
                        provinceField: 'prov',
                        cityField: 'city',
                        areaField: 'area',
                        required: true,
                        onChange: function (info) {
                            var val = info.code == 0 ? '' : info.code;
                            var area = [];
                            if (!valid.isEmpty(info.province)) area.push(info.province);
                            if (!valid.isEmpty(info.city)) area.push(info.city);
                            if (!valid.isEmpty(info.area)) area.push(info.area);
                            inputObj.val(val);
                            inputObj.attr('area', area.join('/'));
                            if (typeof option['change'] != 'undefined') {
                                eval(option['change'] + '(info,this)');
                            }
                        }
                    };
                    var opt = $.extend({}, defaultOption, option);
                    if (code == '' && opt.required == true) { //初始code为空，且必填时补充
                        inputObj.val('110101');
                        inputObj.attr('area', '北京市/东城区');
                        opt.code = '110101';
                    }
                    $(this).citys(opt);
                });

            })
        }
    },
    ckEditor: function () {
        if ($('.f-ck-editor').length > 0) {
            Do('ckeditor', 'lrz', function () {
                $('.f-ck-editor').each(function () {
                    var name = $(this).attr('name');
                    var $option = $(this).data('option');
                    var toolbar = $(this).data('toolbar');
                    var module = $(this).attr('module');
                    if (valid.isEmpty(toolbar)) {
                        var bodyWidth = $(document.body).width();
                        toolbar = bodyWidth <= 1024 ? 'Basic' : 'Full';
                    }
                    var option = valid.isEmpty($option) ? {} : $option;
                    var defaultOptions = {
                        toolbar: toolbar
                    };
                    var options = $.extend({}, defaultOptions, option);
                    options.customConfig = "/static/system/plugins/ckeditor/" + module + "-config.js";
                    var editor = CKEDITOR.replace(name, options);
                    //增加视频按钮
                    editor.ui.addButton && editor.ui.addButton('html5video', {
                        label: 'Video',
                        command: 'html5video'
                    });
                    //设置变量，方便后续操作
                    Do.setData(name + '_editor', editor);
                });
            });
        }
    },
    upload: function () {
        if ($('.f-upload').length > 0) {
            Do('upload', function () {
                $('.f-upload').each(function () {
                    var _this = $(this);
                    var inputFile = $(_this).find("[type='file']");
                    var uploadBtn = $(_this).find('.upload-btn');
                    inputFile.change(function (e) {
                        uploadHelper.funGetFiles(e, _this);
                    });
                    uploadBtn.click(function () {
                        inputFile.trigger('click');
                    });
                });
            })
        }
    },
    uploadVideo: function () {
        if ($('.upload-video-box').length > 0) {
            Do('upload-video');
        }
    },
    /*
      * 新封装多行数据
      * 增加设置name后的回调 data-setname-after
      * 增加Add后的回调 data-add-after
      * 增加Del后的回调 data-del-after
      */
    inputGroup: function () {
        var $inputGroup = $('.f-input-group');
        if ($inputGroup.length > 0) {
            $inputGroup.each(function () {
                var that = $(this);
                var name = that.data('name');
                var set_after_fun = that.data('setname-after');
                var count = that.find('tbody .item').length;
                that.find('.item').each(function (index, element) {
                    var _that = $(this);
                    _that.find('.btn-up').show();
                    _that.find('.btn-down').show();
                    _that.find('.btn-del').show();
                    _that.find('.btn-add').hide();
                    console.log('index '+ index);
                    console.log('count '+ count);
                    if (index === 0) {
                        _that.find('.btn-up').hide();
                        _that.find('.btn-del').hide();
                    }
                    if (index === (count - 1)) {
                        _that.find('.btn-down').hide();
                        _that.find('.btn-add').show();
                    }
                    _that.find('.item-input').each(function (i, v) {
                        var children_name = $(this).data('name');
                        $(this).attr('name', name + '[' + index + '][' + children_name + ']');
                        if (typeof set_after_fun != 'undefined') {
                            eval(set_after_fun + '(_that,index,$(this),i)');
                        }
                    })
                })
            })
        }
    },
    /*增加一行*/
    inputGroupAdd: function (obj) {
        var that = $(obj).closest('.f-input-group');
        var actionHtml = `
        <a href="javascript:;" onclick="formHelper.inputGroupup(this)" class="btn btn-default btn-up"><i class="mdi mdi-arrow-up"></i> </a>
        <a href="javascript:;" onclick="formHelper.inputGroupdown(this)" class="btn btn-default btn-down"><i class="mdi mdi-arrow-down"></i> </a>
        <a href="javascript:;" onclick="formHelper.inputGroupDel(this)" class="btn btn-danger btn-del"><i class="mdi mdi-delete"></i> </a>
        <a href="javascript:;" onclick="formHelper.inputGroupAdd(this)" class="btn btn-info btn-add"><i class="mdi mdi-plus"></i> </a>
        `;
        var html = that.find('.item:last').prop("outerHTML").replace(/<div class="item-action">[\s\S]*<\/div>/g, actionHtml);
        var add_before_fun = that.data('add-before');
        var add_after_fun = that.data('add-after');
        if (typeof add_before_fun != 'undefined') {
            var ret = eval(add_before_fun + '(that,obj)');
            if (ret === false) return false;
        }
        that.find('tbody').append(html);
        formHelper.inputGroup();
        formHelper.color();
        that.find('.item:last').find('.item-input').each(function () {
            $(this).val('');
        });
        if (typeof add_after_fun != 'undefined') {
            eval(add_after_fun + '(that,obj)');
        }
    },
    /*删除一行*/
    inputGroupDel: function (obj) {
        var that = $(obj).closest('.f-input-group');
        var del_before_fun = that.data('del-before');
        if (typeof del_before_fun != 'undefined') {
            var ret = eval(del_before_fun + '(that,obj)');
            if (ret === false) return false;
        }
        $(obj).closest('.item').remove();
        formHelper.inputGroup();
        var del_after_fun = that.data('del-after');
        if (typeof del_after_fun != 'undefined') {
            eval(del_after_fun + '(that,obj)');
        }
    },
    /*上移*/
    inputGroupup: function (obj) {
        var leftMove = $(obj).closest('.item');   //当前行
        var prevMove = leftMove.prev('.item');  //上一个同级元素
        if (prevMove.length > 0) {   //存在上一个同级元素
            prevMove.insertAfter(leftMove);  //就把它移动到前面
        }
        formHelper.inputGroup();
    },
    /*下移*/
    inputGroupdown: function (obj) {
        var rightMove = $(obj).closest('.item');
        var nextMove = rightMove.next('.item');
        if (nextMove.length > 0) {
            nextMove.insertBefore(rightMove);
        }
        formHelper.inputGroup();
    }
};
//加减乘除计算 Number(1.2).add(1.3).mul(1.4).div(1.5)
var calc = {
    accAdd: function (arg1, arg2) { //加
        var r1, r2, m;
        try {
            r1 = arg1.toString().split(".")[1].length
        } catch (e) {
            r1 = 0
        }
        try {
            r2 = arg2.toString().split(".")[1].length
        } catch (e) {
            r2 = 0
        }
        m = Math.pow(10, Math.max(r1, r2))
        return (arg1 * m + arg2 * m) / m
    },
    accSub: function (arg1, arg2) { //减
        var r1, r2, max, min;
        try {
            r1 = arg1.toString().split(".")[1].length
        } catch (e) {
            r1 = 0
        }
        try {
            r2 = arg2.toString().split(".")[1].length
        } catch (e) {
            r2 = 0
        }
        max = Math.pow(10, Math.max(r1, r2));
        //动态控制精度长度
        min = (r1 >= r2) ? r1 : r2;
        return ((arg1 * max - arg2 * max) / max).toFixed(min)
    },
    accMul: function (arg1, arg2) { //乘
        var max = 0, s1 = arg1.toString(), s2 = arg2.toString();
        try {
            max += s1.split(".")[1].length
        } catch (e) {
        }
        try {
            max += s2.split(".")[1].length
        } catch (e) {
        }
        return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, max)
    },
    accDiv: function (arg1, arg2) { //除法
        var t1 = 0, t2 = 0, r1, r2;
        try {
            t1 = arg1.toString().split(".")[1].length
        } catch (e) {
        }
        try {
            t2 = arg2.toString().split(".")[1].length
        } catch (e) {
        }

        r1 = Number(arg1.toString().replace(".", ""))
        r2 = Number(arg2.toString().replace(".", ""))
        return (r1 / r2) * Math.pow(10, t2 - t1)
    }
};
Number.prototype.add = function (arg) {
    return calc.accAdd(arg, this);
}
Number.prototype.sub = function (arg) {
    return calc.accSub(arg, this);
}
Number.prototype.mul = function (arg) {
    return calc.accMul(arg, this);
}
Number.prototype.div = function (arg) {
    return calc.accDiv(arg, this);
}
juicer.register('json2str', helper.json2str);
juicer.register('dateFormat', helper.dateFormat);
juicer.register('renderSize', helper.renderSize);

